/**
 * 
 */
package com.glela.common;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.glela.common.constant.ClientType;
import com.glela.common.constant.CommonConstants;
import com.glela.platform.constant.ErrorEnum;
import com.glela.platform.mapper.TokenMapper;
import com.glela.platform.model.Token;
import com.glela.platform.model.response.ResponseResultModel;
import com.glela.platform.service.TokenService;

/**
 * @author liujie
 *
 */
public class Interceptors implements HandlerInterceptor {
	private static Logger logger = LoggerFactory.getLogger(Interceptors.class);
	private static final String USER_TOKEN = "userToken";
	private static final String USER_ID = "userId";

	@Resource
	private TokenService tokenService;
	@Resource
	private TokenMapper tokenMapper;
	
	/* (non-Javadoc)
	 * @see org.springframework.web.servlet.HandlerInterceptor#afterCompletion(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.Object, java.lang.Exception)
	 */
	@Override
	public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
			throws Exception {
		// TODO Auto-generated method stub

	}

	/* (non-Javadoc)
	 * @see org.springframework.web.servlet.HandlerInterceptor#postHandle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.Object, org.springframework.web.servlet.ModelAndView)
	 */
	@Override
	public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
			throws Exception {
		// TODO Auto-generated method stub

	}

	/* (non-Javadoc)
	 * @see org.springframework.web.servlet.HandlerInterceptor#preHandle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.Object)
	 */
	@Override
	public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws IOException {
		
		/**********************************************************/
		/****** BEGIN MODIFY 修改token验证逻辑 BY liujie ********/
		/**********************************************************/
	 
		boolean res = false;
		arg1.setCharacterEncoding("UTF-8");  
		arg1.setContentType("application/json; charset=utf-8"); 
		String clientType = ClientType.APP;
		if(arg0.getHeader("phoneType") != null && arg0.getHeader("phoneType").length() > 0) {
			if(arg0.getHeader("phoneType").toLowerCase().equals(CommonConstants.PHONE_CLIENT_IOS) || arg0.getHeader("phoneType").toLowerCase().equals(CommonConstants.PHONE_CLIENT_ANDROID)){
				clientType = ClientType.APP;
			} else if(arg0.getHeader("phoneType").toLowerCase().equals(CommonConstants.PHONE_CLIENT_h5) || arg0.getHeader("phoneType").toLowerCase().equals(CommonConstants.PHONE_CLIENT_WX)) {
				clientType = ClientType.H5;
			}
			
		}
		//h5该地址不拦截，app正常拦截
		if (arg0.getRequestURI().contains("live/getPullStreamInfo") && ClientType.H5.equals(clientType)){
			return true;
		}
 		if(null != arg0.getHeader(USER_TOKEN)){
			String userId = null;
			if(arg0.getMethod().equals("GET")){
				userId = arg0.getParameter(USER_ID);
			}else{//post
				BufferedReader bufferedReader = null;
				try{
					//获取参数，这里的reader是经过重写后的，否则会导致在action中reader不可用
					bufferedReader = arg0.getReader();
					StringBuilder stringBuilder = new StringBuilder();
					String val = null;
					while((val=bufferedReader.readLine()) != null){
						stringBuilder.append(val);
					}
 					if(stringBuilder.length() > 0){
						String jsonData = stringBuilder.toString();
						Object obj = JSON.parse(jsonData);
						if(obj instanceof JSONObject){
							JSONObject json = (JSONObject)obj;
							userId = checkPara( json);
						}else if(obj instanceof JSONArray){
							//jsonAarryCheck
							JSONArray json = (JSONArray)obj;
							JSONObject[] jsonArray = new JSONObject[json.size()];
							jsonArray = json.toArray(jsonArray);
							for(JSONObject tmp:jsonArray){
								userId = checkPara( tmp);
							}
						}
 					}
				} catch (IOException e) {
					logger.error("preHandle异常:" ,e);
				} finally{
					try {
						if(bufferedReader != null){
							bufferedReader.close();
						}
					} catch (IOException e) {
						logger.error("preHandle异常:" ,e);
					}
				} 
			}
			
			Token searchToken = new Token();
			searchToken.setCode(arg0.getHeader(USER_TOKEN));
			searchToken.setClientType(clientType);
			if(StringUtils.isNotBlank(userId)){//存在userId参数时，则根据userId与token同时验证，否则只验证token
				searchToken.setUserId(Long.valueOf(userId));
				
			}else {
				if(!StringUtils.isBlank(arg0.getHeader("userId"))) {
					searchToken.setUserId(Long.valueOf(arg0.getHeader("userId")));
				}
				
//				else
//				{
//					//张云飞20180109修改，凡是登录验证的地方必须同时提交 userId 和 TOKEN
//					logger.error("框架权限校验时发生错误，原因: 提交参数缺少userId");
//					Object ps = JSONObject.toJSON(new ResponseResultModel<Object>(ErrorEnum.C20003,null));
//					PrintWriter writer = arg1.getWriter();
//					writer.append(ps.toString());
//					writer.close();
//					return false;
//				}
			}
			
			Token token = null;
			if(searchToken.getUserId() == null || searchToken.getUserId() <= 0) {
				//兼容老版本没有传 USERID参数，无法从缓存校验必走数据库根据TOKEN ，后面版本加入了USERID
				token = tokenMapper.selectToken(searchToken);
			}else {
				token = tokenService.isLogin(searchToken);
			}
			res = token != null;
		}
		//token 验证失败
		if(!res){
 			Object ps = JSONObject.toJSON(new ResponseResultModel<Object>(ErrorEnum.C20100,null));
			PrintWriter writer = arg1.getWriter();
			writer.append(ps.toString());
			writer.close();
  		}
		
		/**********************************************************/
		/****** END MODIFY 修改token验证逻辑 BY liujie ********/
		/**********************************************************/
		
		return res;
	}
	
	private String checkPara(JSONObject json){
		String userId = null;
		Object uid = json.get(USER_ID);
 		if(uid != null){
			userId = uid.toString();
		}
		return userId;
	}
	
}
